package com.itita.ww2.handler.requesthandler.pay;

import java.sql.SQLException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.itita.ww2.core.MessageHandler;
import com.itita.ww2.core.ServerService;
import com.itita.ww2.core.WW2Exception;
import com.itita.ww2.data.shop.PaymentConfig;
import com.itita.ww2.game.pay.PaymentManager;
import com.itita.ww2.game.user.UserInventoryManager;
import com.itita.ww2.game.user.UserService;
import com.itita.ww2.model.user.UserProfile;
import com.itita.ww2.puredb.model.UserPaylog;
import com.itita.ww2.utils.TimeUtil;
import com.itita.ww2.utils.channel.google.GooglePaymentVerifier;
import com.itita.ww2.utils.channel.payment.GoogleOrderInfo;
import com.itita.ww2.utils.handler.IRequestOper;
import com.itita.ww2.utils.properties.ServerProperties;
import com.smartfoxserver.v2.entities.User;
import com.smartfoxserver.v2.entities.data.ISFSObject;
import com.smartfoxserver.v2.entities.data.SFSObject;

/**
 * 谷歌支付
 * @edit NorthLan
 *
 */
public class GooglePay implements IRequestOper {
	private static final Logger logger = LoggerFactory.getLogger(GooglePay.class);

	@Override
	public boolean execute(String requestCMD, User user, ISFSObject params) throws WW2Exception, SQLException {
		UserProfile userProfile = UserService.getInstance().getUserProfile(user);
		// 
		JsonObject receiptObj = new JsonParser().parse(params.getUtfString("code")).getAsJsonObject();
		JsonObject receiptJsonObj = new JsonParser().parse(receiptObj.get("json").getAsString()).getAsJsonObject();
		// 
		String packageName = receiptJsonObj.get("packageName").getAsString();// 包名
		String productId = receiptJsonObj.get("productId").getAsString();// 商品名(完整)
		String token = receiptJsonObj.get("purchaseToken").getAsString();// 凭证
		String developerPayload = receiptJsonObj.get("developerPayload").getAsString(); // 透传信息
		int purchaseState = receiptJsonObj.get("purchaseState").getAsInt();
		// 支付状态 前置验证
		if (purchaseState != 0) {
			logger.error("purchaseSucc: false");
			throw new WW2Exception();
		}
		// 订单号 前置验证
		if (!PaymentManager.getInstance().isOrderInfoExists(userProfile, developerPayload)) {
			logger.error("orderId invalid!");
			throw new WW2Exception();
		}

		GoogleOrderInfo info = null;
		// @formatter:off
		GooglePaymentVerifier verifier = new GooglePaymentVerifier.Builder()
				.setAccessToken(ServerService.getInstance().getGoogleAccessToken())
				.setPackageName(packageName)
				.setProductId(productId)
				.setPurchaseToken(token)
				.build();
		// @formatter:on
		if (ServerProperties.getBoolean("proxy.enable")) {
			verifier.getBuilder().setProxy(ServerProperties.getString("proxy.type"),
					ServerProperties.getString("proxy.ip"), ServerProperties.getInt("proxy.port"));
		}
		info = verifier.verify();
		if (info == null) {
			logger.error("verify error!");
			throw new WW2Exception();
		}
		// 验证状态 后置验证
		if (!info.isValidateSucc()) {
			logger.error("validate error! purchaseSucc:{}, consumptionSucc:{}", info.isPurchaseSucc(),
					info.isConsumptionSucc());
			throw new WW2Exception();
		}
		// 验证成功
		PaymentManager.getInstance().removeOrderInfo(userProfile); // 移除订单号

		ISFSObject backObj = SFSObject.newInstance();
		UserInventoryManager inventory = userProfile.getInventory();
		inventory.backup();
		try {
			backObj = userProfile.getPaymentMgr().onPayment(info.getSKU());
		} catch (Exception e) {
			inventory.rollback();
			throw e;
		} finally {
			inventory.clean();
		}
		if (backObj.containsKey("item")) {
			inventory.update();
			backObj.putSFSArray("inventory", inventory.toSFSArray());
		}
		// 记录数据库
		UserPaylog payLog = new UserPaylog();
		payLog.setSKU(info.getSKU());
		if (receiptJsonObj.has("orderId")) {
			payLog.setOrderId(receiptJsonObj.get("orderId").getAsString());
		} else {
			payLog.setOrderId(info.getOrderId());
		}
		payLog.setPrice(PaymentConfig.getPriceBySKU(info.getSKU()));
		payLog.setUid(userProfile.getUid());
		payLog.setPayTime(TimeUtil.getUtcNowMillis());
		payLog.insert();

		backObj.putUtfString("orderId", payLog.getOrderId());

		MessageHandler.getInstance().sendMsg(requestCMD, backObj, user, null, true);
		return true;
	}
}
